import React, { ComponentClass, ReactNode } from 'react'
import { View, DeviceEventEmitter, NativeEventEmitter } from 'react-native'

export const portalHostContext = React.createContext({})
const TopViewEventEmitter = DeviceEventEmitter || new NativeEventEmitter()
let portalId = 0
const AddEvent = 'PORTAL_ADD_EVENT_TYPE'
const RemoveEvent = 'PORTAL_REMOVE_EVENT_TYPE'

interface PortalItem {
  id: number;
  children: ComponentClass | ReactNode;
}
interface State{
  portals: PortalItem[];
}

export default class PortalHost extends React.Component<{}, State> {
  public constructor (props: {}) {
    super(props)
    this.state = {
      portals: []
    }
  }

  public static add (child: React.ReactNode | any): number {
    const key = ++portalId
    TopViewEventEmitter.emit(AddEvent, child, key)
    return key
  }

  public static remove (key: number, data: any): void {
    TopViewEventEmitter.emit(RemoveEvent, key, data)
  }

  public componentWillMount (): void {
    TopViewEventEmitter.addListener(AddEvent, this._mount.bind(this))
    TopViewEventEmitter.addListener(RemoveEvent, this._unmount.bind(this))
  }

  public componentWillUnmount (): void {
    TopViewEventEmitter.removeListener(AddEvent, this._mount.bind(this))
    TopViewEventEmitter.removeListener(RemoveEvent, this._unmount.bind(this))
  }

  public _mount (children: ComponentClass, key?: number): number {
    key = key || ++portalId
    const portals = this.state.portals || []
    portals.push({ id: key, children })
    this.setState({ portals })
    return key
  }

  public _unmount (key: number): void {
    this.setState((state: State): State => {
      return {
        portals: state.portals.filter((item): boolean => item.id !== key)
      }
    })
  }

  public render (): ReactNode {
    return (
      <portalHostContext.Provider value={{}}>
        <View style={{ flex: 1 }}>
          {this.props.children}
        </View>
        {
          this.state.portals.map((_ref: PortalItem): ReactNode => {
            return React.createElement(View, { key: _ref.id }, _ref.children)
          })
        }
      </portalHostContext.Provider>
    )
  }
}
